package top.raoqq.sky.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import top.raoqq.sky.context.GlobalContext;
import top.raoqq.sky.entity.sql.Menu;
import top.raoqq.sky.entity.sql.Role;
import top.raoqq.sky.enums.SkyResponseEnum;
import top.raoqq.sky.exception.BizException;
import top.raoqq.sky.mapper.MenuMapper;
import top.raoqq.sky.mapper.RoleMapper;
import top.raoqq.sky.service.RoleService;
import top.raoqq.sky.util.StringUtils;

import java.time.LocalDate;
import java.util.*;

/**
 * @author 饶奇奇
 * @date 2023/8/14
 */
@Service
@RequiredArgsConstructor
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {
    private static final String ROLE_ID_KEY = "id";
    private static final String ROLE_NAME_KEY = "roleName";
    private final MenuMapper menuMapper;
    @Override
    public List<Map<String, Object>> listRoleId() {
        List<Map<String, Object>> result = new ArrayList<>(16);
        List<Role> roleList = baseMapper.selectList(null);
        roleList.forEach(role -> {
            Map<String, Object> map = new HashMap<>(16);
            map.put(ROLE_ID_KEY, role.getId());
            map.put(ROLE_NAME_KEY, role.getRoleName());
            result.add(map);
        });
        return result;
    }

    @Override
    public void listRolePageCondition(Page<Role> page, String roleName, String roleKey, LocalDate startTime, LocalDate endTime) {
        LambdaQueryWrapper<Role> wrapper = new LambdaQueryWrapper<>();
        if (!StringUtils.isBlank(roleName)) {
            wrapper.like(Role::getRoleName, roleName);
        }
        if (!StringUtils.isBlank(roleKey)) {
            wrapper.eq(Role::getRoleKey, roleKey);
        }
        //查询创建时间内要从大于等于开始日期的0点0分小于结束日期的后一天的0点0分
        if (Objects.nonNull(startTime)) {
            wrapper.ge(Role::getCreateTime, startTime);
        }
        if (Objects.nonNull(endTime)) {
            wrapper.lt(Role::getCreateTime, endTime.plusDays(1));
        }
        wrapper.orderByAsc(Role::getRoleSort);
        wrapper.orderByDesc(Role::getCreateTime);
        baseMapper.selectPage(page, wrapper);
        List<Role> roleMenuDTOList = baseMapper.getRoleMenuDTOList();
        // 绑定菜单
        page.getRecords().forEach(role -> {
            for (Role roleMenuDTO : roleMenuDTOList) {
                if (role.getId().equals(roleMenuDTO.getId())) {
                    role.setMenuIdList(roleMenuDTO.getMenuIdList());
                }
            }
        });
    }

    @Override
    public void checkSaveOrUpdateArguments(Role role) {
        // 其他数据JSR303校验过了
        List<Long> menuIdList = role.getMenuIdList();
        if (!CollectionUtils.isEmpty(menuIdList)) {
            // 不能小于等于0
            for (Long menuId : menuIdList) {
                if (menuId <= 0) {
                    throw new BizException(SkyResponseEnum.ARGUMENTS_ERROR);
                }
            }
            // 检查菜单是否存在
            LambdaQueryWrapper<Menu> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(Menu::getMenuId, menuIdList);
            // id是否全部存在
            boolean menuIdListExits = Long.valueOf(menuIdList.size()).equals(menuMapper.selectCount(wrapper));
            if(!menuIdListExits) {
                throw new BizException(SkyResponseEnum.ARGUMENTS_ERROR);
            }
        }
    }

    @Override
    public void saveOrUpdateRole(Role role) {
        Long id = role.getId();
        if (Objects.nonNull(id)) {
            role.setUpdateBy(GlobalContext.getUsername());
            // 如果是修改德话删除之前绑定的菜单
            baseMapper.unBindMenu(id);
        } else {
            role.setCreateBy(GlobalContext.getUsername());
        }
        // 新增修改角色表
        saveOrUpdate(role);
        List<Long> menuIdList = role.getMenuIdList();
        if (!CollectionUtils.isEmpty(menuIdList)) {
            // 绑定菜单
            baseMapper.bindMenu(role.getId(), role.getMenuIdList());
        }
    }

    @Override
    public void unBindMenu(Long roleId) {
        baseMapper.unBindMenu(roleId);
    }
}
